package com.sailing.xjpb.orm.query;

import com.sailing.xjpb.orm.utils.SqlUtils;
import org.apache.commons.lang3.tuple.Pair;

import java.util.Arrays;
import java.util.Collection;
import java.util.Map;

/**
 * 条件类型枚举，规定了查询条件中的SQL比对符号
 *
 * @author YaoWei
 * createTime 2015年7月27日 上午11:11:26
 */
public enum ConditionType {
    /**
     * 等于
     */
    EQ {
        @Override
        public ConditionUnit getConditionUnit(String column, String paramKey, Object value) {
            String parameterKey = SqlUtils.getParameterKey(paramKey);
            StringBuilder sql = new StringBuilder();
            sql.append(" and ").append(column).append("=").append(parameterKey);
            return ConditionUnit.of(sql).addParam(paramKey, value);
        }
    },
    /**
     * 不等于
     */
    NOT_EQ {
        @Override
        public ConditionUnit getConditionUnit(String column, String paramKey, Object value) {
            String parameterKey = SqlUtils.getParameterKey(paramKey);
            StringBuilder sql = new StringBuilder();
            sql.append(" and ").append(column).append("!=").append(parameterKey);
            return ConditionUnit.of(sql).addParam(paramKey, value);
        }
    },
    /**
     * 模糊比对 %value%
     */
    LIKE {
        @Override
        public ConditionUnit getConditionUnit(String column, String paramKey, Object value) {
            String parameterKey = SqlUtils.getParameterKey(paramKey);
            StringBuilder sql = new StringBuilder();
            sql.append(" and ").append(column).append(" like ").append(parameterKey);
            return ConditionUnit.of(sql).addParam(paramKey, "%" + value + "%");
        }
    },
    /**
     * 模糊比对 %value
     */
    LEFT_LIKE {
        @Override
        public ConditionUnit getConditionUnit(String column, String paramKey, Object value) {
            String parameterKey = SqlUtils.getParameterKey(paramKey);
            StringBuilder sql = new StringBuilder();
            sql.append(" and ").append(column).append(" like ").append(parameterKey);
            return ConditionUnit.of(sql).addParam(paramKey, "%" + value);
        }
    },
    /**
     * 模糊比对 value%
     */
    RIGHT_LIKE {
        @Override
        public ConditionUnit getConditionUnit(String column, String paramKey, Object value) {
            String parameterKey = SqlUtils.getParameterKey(paramKey);
            StringBuilder sql = new StringBuilder();
            sql.append(" and ").append(column).append(" like ").append(parameterKey);
            return ConditionUnit.of(sql).addParam(paramKey, value + "%");
        }
    },
    /**
     * 模糊比对
     */
    NOT_LIKE {
        @Override
        public ConditionUnit getConditionUnit(String column, String paramKey, Object value) {
            String parameterKey = SqlUtils.getParameterKey(paramKey);
            StringBuilder sql = new StringBuilder();
            sql.append(" and ").append(column).append(" not like ").append(parameterKey);
            return ConditionUnit.of(sql).addParam(paramKey, "%" + value + "%");
        }
    },
    /**
     * 小于等于
     */
    LE {
        @Override
        public ConditionUnit getConditionUnit(String column, String paramKey, Object value) {
            String parameterKey = SqlUtils.getParameterKey(paramKey);
            StringBuilder sql = new StringBuilder();
            sql.append(" and ").append(column).append("<=").append(parameterKey);
            return ConditionUnit.of(sql).addParam(paramKey, value);
        }
    },
    /**
     * 大于等于
     */
    GE {
        @Override
        public ConditionUnit getConditionUnit(String column, String paramKey, Object value) {
            String parameterKey = SqlUtils.getParameterKey(paramKey);
            StringBuilder sql = new StringBuilder();
            sql.append(" and ").append(column).append(">=").append(parameterKey);
            return ConditionUnit.of(sql).addParam(paramKey, value);
        }
    },
    /**
     * 小于等于
     */
    LT {
        @Override
        public ConditionUnit getConditionUnit(String column, String paramKey, Object value) {
            String parameterKey = SqlUtils.getParameterKey(paramKey);
            StringBuilder sql = new StringBuilder();
            sql.append(" and ").append(column).append("<").append(parameterKey);
            return ConditionUnit.of(sql).addParam(paramKey, value);
        }
    },
    /**
     * 大于等于
     */
    GT {
        @Override
        public ConditionUnit getConditionUnit(String column, String paramKey, Object value) {
            String parameterKey = SqlUtils.getParameterKey(paramKey);
            StringBuilder sql = new StringBuilder();
            sql.append(" and ").append(column).append(">").append(parameterKey);
            return ConditionUnit.of(sql).addParam(paramKey, value);
        }
    },
    /**
     * in (?,?)
     */
    IN {
        @Override
        public ConditionUnit getConditionUnit(String column, String paramKey, Object value) {
            Collection<?> values = ConditionType.getInParams(value);
            Pair<String, Map<String, Object>> sqlIn = SqlUtils.getSqlIn(paramKey, values);
            StringBuilder sql = new StringBuilder();
            sql.append(" and ").append(column).append(" in ").append(sqlIn.getLeft());
            return ConditionUnit.of(sql).addAllParam(sqlIn.getRight());

        }
    },
    /**
     * not in (?,?)
     */
    NOT_IN {
        @Override
        public ConditionUnit getConditionUnit(String column, String paramKey, Object value) {
            Collection<?> values = ConditionType.getInParams(value);
            Pair<String, Map<String, Object>> sqlIn = SqlUtils.getSqlIn(paramKey, values);
            StringBuilder sql = new StringBuilder();
            sql.append(" and ").append(column).append(" not in ").append(sqlIn.getLeft());
            return ConditionUnit.of(sql).addAllParam(sqlIn.getRight());

        }
    };

    /**
     * 根据查询条件类型获取查询条件单元
     *
     * @param column   列名
     * @param paramKey 注入参数名称
     * @param value    查询条件的值
     */
    public abstract ConditionUnit getConditionUnit(String column, String paramKey, Object value);

    /**
     * 将查询条件的值转换为多个值
     *
     * @param paramValue 查询条件的值
     */
    public static Collection<?> getInParams(Object paramValue) {
        if (paramValue instanceof Collection) {
            return (Collection<?>) paramValue;
        } else {
            Object[] paramValues = String.valueOf(paramValue).split(",");
            return Arrays.asList(paramValues);
        }
    }
}
